package mysql

import (
	"go-ddd-ecommerce/internal/domain/order"
	"time"

	"github.com/google/uuid"
	"gorm.io/gorm"
)

// 基础设施层实现仓储层的接口

// 数据库映射的模型
type OrderModel struct {
	// Id因为修改成了uuid，所以就不组合gorm的字段进来了
	Id string `gorm:"column:id;primaryKey"`
	// 购买商品的用户id
	UserID string `gorm:"not null" json:"user_id"`
	// 购买的商品id
	ProductID string `gorm:"not null" json:"product_id"`
	// 购买商品的数量
	Quantity int `gorm:"not null" json:"quantity"`
	// 订单总价
	TotalAmount float64 `gorm:"not null" json:"total_amount"`
	// 订单状态
	Status string `gorm:"not null;default:'completed'" json:"status"`

	// GORM 管理字段
	CreatedAt time.Time
	UpdatedAt time.Time
	DeletedAt gorm.DeletedAt `gorm:"index"`
}

// TableName 指定表名
func (OrderModel) TableName() string {
	return "orders"
}

// ToDomain 映射成领域模型
func (o *OrderModel) ToDomain() *order.Order {
	return &order.Order{
		ID:          uuid.MustParse(o.Id),
		UserID:      uuid.MustParse(o.UserID),
		ProductID:   uuid.MustParse(o.ProductID),
		Quantity:    o.Quantity,
		TotalAmount: o.TotalAmount,
		Status:      o.Status,
		CreatedAt:   o.CreatedAt,
	}
}

func orderToOrderModel(order *order.Order) *OrderModel {
	return &OrderModel{
		Id:          order.ID.String(),
		UserID:      order.UserID.String(),
		ProductID:   order.ProductID.String(),
		Quantity:    order.Quantity,
		TotalAmount: order.TotalAmount,
		Status:      order.Status,
	}
}

type OrderRepository struct {
	db *gorm.DB
}

func NewOrderRepository(db *gorm.DB) *OrderRepository {
	return &OrderRepository{
		db: db,
	}
}

func (o *OrderRepository) FindByID(id uuid.UUID) (*order.Order, error) {
	var order OrderModel
	if err := o.db.Where("id = ?", id.String()).First(&order).Error; err != nil {
		return nil, err
	}
	return order.ToDomain(), nil
}

func (o *OrderRepository) FindByUserID(userID uuid.UUID) ([]*order.Order, error) {
	var orderList []OrderModel
	result := o.db.Where("user_id = ?", userID).Find(&orderList)
	if result.Error != nil {
		return nil, result.Error
	}
	var orders []*order.Order
	for _, order := range orderList {
		orders = append(orders, order.ToDomain())
	}
	return orders, nil
}

func (o *OrderRepository) Save(order *order.Order) error {
	return o.db.Create(orderToOrderModel(order)).Error
}

//func (o *OrderRepository) Update(order *order.Order) error {
//	return o.db.Save(orderToOrderModel(order)).Error
//}
